package com.ayf.payment.game.api.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.cache.redis.RedisCacheUtil;
import com.ayf.payment.game.api.controller.player.AybSendMsgUtils;
import com.ayf.payment.game.api.dto.AybUserDTO;
import com.ayf.payment.game.api.dto.MerchantDTO;
import com.ayf.payment.game.api.dto.Token;
import com.ayf.payment.game.api.entity.AybUser;
import com.ayf.payment.game.api.entity.Merchant;
import com.ayf.payment.game.api.entity.MerchantSon;
import com.ayf.payment.game.api.service.AybUserService;
import com.ayf.payment.game.api.service.MerchantService;
import com.ayf.payment.game.api.service.MerchantSonService;
import com.ayf.payment.game.api.service.TokenService;
import com.ayf.payment.game.api.service.platform.NetConfigService;
import com.ayf.payment.game.api.type.CommonConstants;
import com.ayf.payment.game.api.type.LoginType;
import com.ayf.payment.game.api.utils.CommonResult;
import com.ayf.payment.game.api.utils.Md5Utils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * @Description: 爱游宝消息控制层
 * @Author: zh-liang
 * @Date : 2021-03-16 11:21
 */
@RestController
@RequestMapping("/v3/merchant/ayb/")
public class AybController {

    @Autowired
    private RedisCacheUtil redisCacheUtil;
    @Autowired
    private AybUserService aybUserService;
    @Autowired
    private AybSendMsgUtils aybSendMsgUtils;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private MerchantSonService merchantSonService;
    @Autowired
    private NetConfigService netConfigService;

    private static final String PLATFORM_KEY = System.getenv("GAME_AYFPAY_PLATFORM_KEY");

    /**
     * 绑定爱游宝账号
     */
    @PostMapping("/bind/{key}")
    public CommonResult<?> bind(@PathVariable("key") String key, AybUserDTO aybUserDTO) {
        Map<String, Object> params = new HashMap<>();
        params.put("aybId", aybUserDTO.getAybId());
        params.put("phone", aybUserDTO.getPhone());
        if (StrUtil.isNotEmpty(aybUserDTO.getNickname())) {
            params.put("nickname", aybUserDTO.getNickname());
        }
        if (StrUtil.isNotEmpty(aybUserDTO.getHeadImgUrl())) {
            params.put("headImgUrl", aybUserDTO.getHeadImgUrl());
        }
        if (!checkSign(aybUserDTO.getSign(), params)) {
            return new CommonResult<>(199, "签名错误");
        }
        MerchantDTO merchantDTO = redisCacheUtil.getObjectFromCache(key);
        if (merchantDTO == null) {
            return new CommonResult<>(-1, "二维码已失效，请重新获取新的二维码");
        }
        AybUser bindAybUser = aybUserService.getBindAybUser(merchantDTO.getId(), merchantDTO.getLoginId());
        if (bindAybUser != null) {
            return new CommonResult<>(-1, "该GM账号已绑定其它爱游宝账号，请先进行解绑！");
        }
        AybUser bindAyb = aybUserService.getBindAybUserByAybId(aybUserDTO.getAybId());
        if (bindAyb != null) {
            return new CommonResult<>(-1, "该爱游宝账号已绑定其它GM账号，请先进行解绑！");
        }
        aybUserDTO.setLoginId(merchantDTO.getLoginId());
        aybUserDTO.setMerchantId(merchantDTO.getId());
        aybUserDTO.setBindTime(new Date());
        int a;
        if (LoginType.FATHER.name().equals(merchantDTO.getLoginType())) {
            a = 1;
        } else if (LoginType.SON.name().equals(merchantDTO.getLoginType())) {
            a = 2;
        } else {
            a = 3;
        }
        aybUserDTO.setType(a);
        aybUserService.add(aybUserDTO);
        aybSendMsgUtils.bindAyb(aybUserDTO);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "绑定成功");
    }

    /**
     * 解绑爱游宝
     */
    @PostMapping("/unbind/{key}")
    public CommonResult<?> unbind(@PathVariable("key") String key, AybUserDTO aybUserDTO) {
        Map<String, Object> params = new HashMap<>();
        params.put("aybId", aybUserDTO.getAybId());
        if (!checkSign(aybUserDTO.getSign(), params)) {
            return new CommonResult<>(199, "签名错误");
        }
        MerchantDTO merchantDTO = redisCacheUtil.getObjectFromCache(key);
        if (merchantDTO == null) {
            return new CommonResult<>(-1, "二维码已失效，请重新获取新的二维码");
        }
        AybUser bindAybUser = aybUserService.getBindAybUser(merchantDTO.getId(), merchantDTO.getLoginId());
        if (bindAybUser != null && aybUserDTO.getAybId().equals(bindAybUser.getAybId())) {
            aybUserService.deleteById(bindAybUser.getId());
            redisCacheUtil.setObjectToCacheDelaySeconds("AYB_UN_BIND_STATUS:" + key, 1, 60 * 60 * 6L);
            int a;
            if (LoginType.FATHER.name().equals(merchantDTO.getLoginType())) {
                a = 1;
            } else if (LoginType.SON.name().equals(merchantDTO.getLoginType())) {
                a = 2;
            } else {
                a = 3;
            }
            aybUserDTO.setType(a);
            aybUserDTO.setLoginId(merchantDTO.getLoginId());
            aybUserDTO.setMerchantId(merchantDTO.getId());
            aybSendMsgUtils.unbindAyb(aybUserDTO);
            return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "解绑成功");
        }
        return new CommonResult<>(-1, "解绑失败，解绑信息不匹配！");
    }

    /**
     * 获取token信息
     */
    @PostMapping("/getToken")
    public CommonResult<?> getToken(AybUserDTO aybUserDTO) {
        Map<String, Object> params = new HashMap<>();
        params.put("aybId", aybUserDTO.getAybId());
        if (!checkSign(aybUserDTO.getSign(), params)) {
            return new CommonResult<>(199, "签名错误");
        }
        AybUser bindAybUser = aybUserService.getBindAybUserByAybId(aybUserDTO.getAybId());
        if (bindAybUser == null) {
            return new CommonResult<>(-1, "获取失败，当前爱游宝账号已解绑");
        }
        String type = "";
        if (bindAybUser.getType() == 1) {
            type = LoginType.FATHER.name();
        } else if (bindAybUser.getType() == 2) {
            type = LoginType.SON.name();
        } else if (bindAybUser.getType() == 3) {
            type = LoginType.TUI_G.name();
        }
        Token token = tokenService.createToken(bindAybUser.getMerchantId(), bindAybUser.getLoginId(), type);
        Map<String, Object> map = new HashMap<>();
        map.put("accessToken", token.getAccessToken());
        map.put("merchantId", token.getMerchantId());
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "获取成功", map);
    }

    private boolean checkSign(String signStr, Map<String, Object> params) {
        if (StrUtil.isBlank(signStr) || CollUtil.isEmpty(params)) {
            String traceId = SnowFlakeUtils.getTraceId();
            LogPortal.error("{} 爱游宝接口签名校检失败，签名原文：{}，params：{}", traceId, signStr, JSONObject.toJSONString(params));
            return false;
        }
        String sign = aybSign(params);
        if (!signStr.equals(sign)) {
            String traceId = SnowFlakeUtils.getTraceId();
            LogPortal.error("{} 爱游宝接口签名校检失败，签名原文：{}，生成的签名为：{}，生成的签名原文为：{}", traceId, signStr, sign, sign);
            return false;
        }
        return true;
    }

    private String aybSign(Map<String, Object> map) {
        List<String> list = new ArrayList<>();
        map.forEach((k, v) -> list.add(k));
        Collections.sort(list);
        StringBuilder str = new StringBuilder("");
        for (String k : list) {
            str.append(k).append("=").append(map.get(k).equals("&"));
        }
        str.append(PLATFORM_KEY);
        String sign = Md5Utils.encode(str.toString());
        if (sign == null) {
            return null;
        }
        return sign.toLowerCase();
    }

    /**
     * 获取爱游宝绑定信息
     */
    @PostMapping("/getBindInfo/{key}")
    public CommonResult<?> getBindInfo(@PathVariable("key") String key, AybUserDTO aybUserDTO) {
        Map<String, Object> params = new HashMap<>();
        params.put("aybId", aybUserDTO.getAybId());
        params.put("timestamp", aybUserDTO.getTimestamp());
        if (!checkSign(aybUserDTO.getSign(), params)) {
            return new CommonResult<>(199, "签名错误");
        }
        AybUser bindAybUser = aybUserService.getBindAybUserByAybId(aybUserDTO.getAybId());

        if (bindAybUser == null) {
            return new CommonResult<>(-1, "请先将爱游宝账号与GM账号绑定");
        }
        Map<String, Object> map = new HashMap<>(8);
        if (bindAybUser.getMerchantId().equals(bindAybUser.getLoginId())) {
            Merchant merchant = merchantService.find(bindAybUser.getLoginId());
            map.put("loginAccount", merchant.getLoginAccount());
        } else {
            MerchantSon merchantSon = merchantSonService.selectInfo(bindAybUser.getLoginId());
            map.put("loginAccount", merchantSon.getLoginAccount());
        }
        map.put("url", netConfigService.getNetConfig().getDomainName() + "/gameapip/v3/merchant/ayb/login/" + key);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "获取成功", map);
    }

    /**
     * 登录爱游宝
     */
    @PostMapping("/login/{key}")
    public CommonResult<?> login(@PathVariable("key") String key, AybUserDTO aybUserDTO) {
        Map<String, Object> params = new HashMap<>();
        params.put("aybId", aybUserDTO.getAybId());
        params.put("timestamp", aybUserDTO.getTimestamp());
        if (!checkSign(aybUserDTO.getSign(), params)) {
            return new CommonResult<>(199, "签名错误");
        }
        AybUser bindAybUser = aybUserService.getBindAybUserByAybId(aybUserDTO.getAybId());
        if (bindAybUser == null) {
            return new CommonResult<>(-1, "请先将爱游宝账号与GM账号绑定");
        }
        String type = "";
        if (bindAybUser.getType() == 1) {
            type = LoginType.FATHER.name();
        } else if (bindAybUser.getType() == 2) {
            type = LoginType.SON.name();
        } else if (bindAybUser.getType() == 3) {
            type = LoginType.TUI_G.name();
        }
        Token token = tokenService.createToken(bindAybUser.getMerchantId(), bindAybUser.getLoginId(), type);
        redisCacheUtil.setObjectToCacheDelaySeconds("AYB_LOGIN_STATUS:" + key, token, 60 * 60L);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "登录成功");
    }
}
